/**
 * 
 */
package com.jintian.smart.kernel.common.expr.op;

import com.jintian.smart.kernel.core.expr.IllegalExpressionException;
import com.jintian.smart.kernel.common.expr.datameta.BaseDataMeta;
import com.jintian.smart.kernel.common.expr.datameta.Constant;

/**
 * 操作符执行接口
 */
public interface IOperatorExecution {

	public Operator getOperator();

	/**
	 * 执行操作符运算
	 * 
	 * @param args
	 *            注意args中的参数由于是从栈中按LIFO顺序弹出的，所以必须从尾部倒着取数
	 * @return Constant 常量型的执行结果
	 * @throws IllegalExpressionException
	 */
	public Constant execute(Constant[] args) throws IllegalExpressionException;

	/**
	 * 验证操作符参数是否合法
	 * 
	 * @param opPositin
	 * @param args
	 *            注意args中的参数由于是从栈中按LIFO顺序弹出的，所以必须从尾部倒着取数
	 * @return Constant 常量型的执行结果
	 * @throws IllegalExpressionException
	 */
	public Constant verify(int opPositin, BaseDataMeta[] args) throws IllegalExpressionException;

	default void checkParameterCount(int opPositin, BaseDataMeta[] args) {
		if (args == null || args.length != this.getOperator().getOpType()) {
			// 抛异常
			throw new IllegalExpressionException("操作符\"" + getOperator().getToken() + "\"需要"
					+ this.getOperator().getOpType() + "个参数，实际为" + (args == null ? 0 : args.length) + "个",
					getOperator().getToken(), opPositin);
		}

		for (int i = 0; i < args.length; i++) {
			BaseDataMeta m = args[i];
			if (m == null) {
				throw new NullPointerException("操作符\"" + getOperator().getToken() + "\"第" + (args.length - i) + "参数为空");
			}
		}
	}
}
